package com.lulin.mall.product.thread;

import java.util.concurrent.*;

/**
 * ComplatableFuture异步编排介绍
 *
 * @author lulin
 * @date 2022/12/1 10:34
 */
public class ComplatableFutureDome3 {
    //创建1个线程池对象
    private static ThreadPoolExecutor poolExecutor = new ThreadPoolExecutor(5, 50, 10,
            TimeUnit.SECONDS,
            new LinkedBlockingDeque<>(100),
            Executors.defaultThreadFactory(),
            new ThreadPoolExecutor.AbortPolicy()
    );

    /**
     * 2个方法都完成
     *
     * @param args
     * @throws ExecutionException
     * @throws InterruptedException
     */
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        CompletableFuture<Integer> future1 = CompletableFuture.supplyAsync(() -> {
            System.out.println("任务1 线程开始了..." + Thread.currentThread().getName());
            int i = 100 / 5;
            System.out.println("任务1 线程结束了..." + Thread.currentThread().getName());
            return i;
        }, poolExecutor);
        CompletableFuture<Integer> future2 = CompletableFuture.supplyAsync(() -> {
            System.out.println("任务2 线程开始了..." + Thread.currentThread().getName());
            int i = 100 / 10;
            System.out.println("任务2 线程结束了..." + Thread.currentThread().getName());
            return i;
        }, poolExecutor);

        // runAfterBothAsync：不能获取前面两个线程的返回结果，本身没有返回结果
        CompletableFuture<Void> voidCompletableFuture = future1.runAfterBothAsync(future2, () -> {
            System.out.println("任务3执行了");
        }, poolExecutor);
        // thenAcceptBothAsync：可以获取前面2个线程的返回结果，本身没有返回结果
        CompletableFuture<Void> voidCompletableFuture1 = future1.thenAcceptBothAsync(future2, (f1, f2) -> {
            System.out.println("f1 = " + f1);
            System.out.println("f2 = " + f2);
        }, poolExecutor);

        // thenCombineAsync: 既可以获取前面两个线程的返回结果，同时也会返回结果给阻塞的线程
        CompletableFuture<String> stringCompletableFuture = future1.thenCombineAsync(future2, (f1, f2) -> {
            return f1 + ":" + f2;
        }, poolExecutor);

        // 可以处理异步任务之后的操作
        System.out.println("获取的线程的返回结果是：" + stringCompletableFuture.get());

    }
}
